GDAS010-Bioconductor中的基因组注释

Interaction beyond the “read-eval-print” loop

在R语言中,除了使用命令行模式来分析数据外,还可以使用图形用户界面(GUI)来分析数据,Rstudio中有一个shiny包,它可以创建GUI。

dfHclust函数

主要布局

ph525x包中含有dfHclust 函数,我们使用这个函数来展示一个数据,这个数据是数据框类型,,如下所示:

1
2
library(ph525x)
dfHclust(mtcars)

注:由于ph525x 这个包有点老了,可以直接去官网找到这个包中函数dfHclust()源代码来运行上述命令,运行结果如下所示:

左侧是侧边栏,里面有这些内容:

  • distance :用于聚类的距离类型;
  • clustering method :用于聚类的方法;to form the hierarchy through object agglomeration
  • height :用于聚类的系统树的切割高度,将其分为几组;
  • 最下面是参与计算距离的一些特征值(变量)。

在这个案例中,我们所研究的对象是不同制造商和型号的汽车;特征值是这些汽车的结构或操作特性。我们注意一下,我们在启动这个交互页面时,我们的默认选项如下所示:

  • euclidean距离
  • 聚类算法是ward.D
  • 在40处进行切割
  • 前两个变量作为特征值

右侧图形包括了几个选项卡,如下所示:

  • 聚类树;
  • 两两配对的散点图(就是在pairs这个选项卡上),如下所示:

  • 用于评估所选的切割高度下聚类质量的轮廓图,如下所示:

为了充分理解聚类中treesilh选项卡中所显示的数量,用户应该查看距离(distance)、聚类方法(clustering method)和轮廓(silhouette)的具体参数,直接你能简洁明了地向非统计人员解释这些内容,具体参数含义如下:

要完全理解“tree”和“silh”选项卡中显示的数量,您应该查看距离、聚类方法和轮廓的定义,直到您愿意向非统计人员解释这些内容。

  • 距离(Distance)是多元分析中非常重要的一个参数;
  • 聚类程序(Hierarchical clustering procedures)有点复杂;具体的可能参考Wiki百科中的 definition of Ward’s method ,或者我以前的笔记。
  • 轮廓(Silhouett)的定义可以查看cluster包中的 silhouette 文档。

与显示界面交互

需要注意的是,当选择tree选项卡时,默认情况下,页面展示的一个具有三个主干的树,而silh选项卡则展示了聚类成员的在每个主干树中的检测值(这个值是怎么算的,先不用管),这三个值是通过设计cut的值来将树切为三个主干分别进行计算的,通过silh选项卡,我们知道以下内容:

  • 平均silhouette的宽度是0.56;
  • 如果改动Select height for cut,将其改为70,那么silhouette图也会改变,它的平均值就会变为0.59,这个值变大的,并且我们看到,在silh页面,我们只能看到两个聚类结果的计算值,并且还有一个silhouette是负值;
  • 我们还可以改变距离(distance)参数,聚类方法等,这些参数都能改变聚类树的形状。

A view of the code

在这一小节中,我们将看一下 dfHclust 函数的源代码,并且解释一下其中的元素。这些代码是以一种非常简洁直白的方式书写的,但它有三个优点:

  • 代码相对较短,并且能独立运行;
  • 在交互式数据探索中能运行良好,并发挥相应作用;
  • 通过复制和修改可以轻松扩展。

但是也有一些地方需要改进:

  • ui组件中处理全局变量;
  • data.frame重复过多,server组件中构建的子集data.frame过多。

开始

我们有一个简单的固定接口,如果函数参数中没有2个以上的data.frame,那么就会抛出错误。如果没有安装相应的包,那么也会抛出错误,如下所示:

1
2
3
4
5
6
7
dfHclust = function(df) {
# validate input
stopifnot(inherits(df, "data.frame"))
stopifnot(ncol(df)>1)
# obtain software
require(shiny)
require(cluster)

用于填写参数的一些向量

1
2
3
4
5
6
7
# global variables ...
nms = names(df)
cmeths = c("ward.D", "ward.D2",
"single", "complete", "average", "mcquitty",
"median", "centroid")
dmeths = c("euclidean", "maximum", "manhattan", "canberra",
"binary")

用户界面的布局

还有几个高级选项用于控制浏览器的界面。现在我们将使用一种名为fluidPage;也可以参考shinydashboard 包,如下所示:

1
2
3
4
5
6
7
8
9
#
# main shiny components: ui and server
# ui: defines page layout and components
# server: defines operations
#
ui <- fluidPage(
#
# we will have four components on sidebar: selectors for
# distance, agglomeration method, height for tree cut, and variables to use

标题和侧边栏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
titlePanel(paste(substitute(df), "hclust")),
sidebarPanel(
helpText(paste("Select distance:" )),
fluidRow(
selectInput("dmeth", NULL, choices=dmeths,
selected=dmeths[1])),
helpText(paste("Select clustering method:" )),
fluidRow(
selectInput("meth", NULL, choices=cmeths,
selected=cmeths[1])),
helpText(paste("Select height for cut:" )),
fluidRow(
numericInput("cutval", NULL, value=40, min=0, max=Inf, step=1)),
helpText(paste("Select variables for clustering from", substitute(df), ":" )),
fluidRow(
checkboxGroupInput("vars", NULL, choices=nms,
selected=nms[1:2]))
),

显示的主要选项卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#
# main panel is a simple plot
#
mainPanel(
tabsetPanel(
tabPanel("tree",
plotOutput("plot1")),
tabPanel("pairs",
plotOutput("pairsplot")),
tabPanel("silh",
plotOutput("silplot"))
)
)
) # end fluidPage

定义服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#
# a function with up to three arguments (input, output, session)
# can be used to define the server component of the app
# renderPlot makes it reactive, so when input components are altered,
# data frame in use and plot are updated
#
server <- function(input, output) {
output$plot1 <- renderPlot({
xv = df[,input$vars]
plot(hclust(dist(data.matrix(xv),method=input$dmeth), method=input$meth),
xlab=paste(input$dmeth, "distance;", input$meth, "clustering"))
abline(h=input$cutval, lty=2, col="gray")
})
output$pairsplot <- renderPlot({
xv = df[,input$vars]
pairs(data.matrix(xv))
})
output$silplot <- renderPlot({
xv = df[,input$vars]
dm = dist(data.matrix(xv),method=input$dmeth)
hc = hclust(dist(data.matrix(xv),method=input$dmeth), method=input$meth)
ct = cutree(hc, h=input$cutval)
plot(silhouette(ct, dm))
})
}
shinyApp(ui, server)
}

一些重要细节

一个shiny app含有两个主要组件,一个是用户界面,一个是服务器函数。为了使用这个UI界面,R中必须要加载shiny包。我们可以通过各种方式来使用户界面;我们使用的是shinyApp并且支持两个参数uiserver。如下所示:

  • uishiny.tag.list的一个实例。你可以通过检查fluidPage()的结果来感受一下这个实例。

  • server 是一个函数,它有三个参数,分别为 input, output and session;最后一个参数是可选的。input是一个列表,它与ui 中给定的值绑定,ouput 会将服务器中的元素填充到UI中(这段话不太理解,原文如下):

    server is a function of three arguments input, output and session; the latter is optional. input is a list with bindings given values in the ui component, and output will be populated with elements in the server for rendering in the UI.

fluidPage的一个案例

使用以下代码就可以查看shiny是如何运行的,如下所示:

1
2
3
4
5
6
7
library(shiny)
fluidPage(
titlePanel("a title"),
sidebarPanel(
selectInput("seli1", "some letters", letters[1:4])
)
)

设置sink(file="dem.html")参数,并再次运行上述代码。然后就出现sink(NULL); browseURL("dem.html")。R将启动浏览器并显示出一个非常简洁的页面。这个页面中会出现含有a,…d的选择控件。

这个特殊的案例很容易用手写代码,但是selectInput函数可以允许你开发具有任何R向量定义的选择的控件。此外,高级R函数还可以允许输入不同的类型,用鼠标还可以驱动这些事件。

参考资料

  1. shiny for interactive visualization of multivariate data